package view;

import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import model.IModel;
import model.IModelObserver;
import model.Model.Status;
import model.Sprite;

/*
 * 
 * LemonPanel class
 * 
 * Responsible for displaying the lemon character and any screen overlays.
 * 
 */

public class LemonPanel extends JPanel implements IModelObserver {

	private static final long serialVersionUID = -3698108646351684644L;
	private IModel model;
	private JLabel lemon;
	private JLabel gameOverScreen;
	private JLabel pauseScreen;
	private JLabel loadingScreen;
	private JLabel level;
	private String currentLevel;
	private JLabel lives;
	private String currentLives;
	private JLabel health;
	private String currentHealth;
	private Point lemonPosition;
	Map<Sprite, ImageIcon> lemonSpriteMap = new HashMap<Sprite, ImageIcon>();

	/**
	 * LemonPanel
	 * 
	 * loads all of the screens for the game, as well as adding them to the
	 * mainFrame
	 * 
	 * @param m
	 */
	public LemonPanel(IModel m) {
		setLayout(null);
		setVisible(true);
		setSize(800, 600);
		setLocation(0, 0);
		setBackground(Color.BLUE);
		model = m;
		pauseScreen = new JLabel();
		pauseScreen.setSize(800, 600);
		pauseScreen.setOpaque(false);

		loadingScreen = new JLabel();
		loadingScreen.setSize(800, 600);
		loadingScreen.setOpaque(false);

		java.awt.Font font = new java.awt.Font("system", Font.PLAIN, 36);

		gameOverScreen = new JLabel();
		gameOverScreen.setSize(800, 600);
		gameOverScreen.setOpaque(false);
		gameOverScreen.setVisible(false);

		level = new JLabel();
		level.setSize(100, 100);
		level.setOpaque(false);
		level.setForeground(Color.WHITE);
		level.setFont(font);
		level.setLocation(475, 182);

		lives = new JLabel();
		lives.setSize(100, 100);
		lives.setOpaque(false);
		lives.setForeground(Color.WHITE);
		lives.setFont(font);
		lives.setLocation(435, 250);

		health = new JLabel();
		health.setSize(200, 50);
		health.setOpaque(false);
		health.setForeground(Color.WHITE);
		health.setFont(font);
		health.setLocation(0, 0);

		lemon = new JLabel();
		lemon.setSize(50, 50);
		lemon.setVisible(true);
		lemonPosition = new Point();
		lemonPosition.x = this.getWidth() / 2 - lemon.getWidth() / 2;
		lemonPosition.y = this.getHeight() / 2;
		lemon.setLocation(lemonPosition);
		add(gameOverScreen);
		add(pauseScreen);
		add(level);
		add(lives);
		add(loadingScreen);
		add(health);
		add(lemon);

		importSprites();

		lemon.setIcon(lemonSpriteMap.get(Sprite.LEMONR0));
	}

	/**
	 * importSprite
	 * 
	 * loads sprites based upon the passed in path
	 * 
	 * @param path
	 * @return
	 */
	private ImageIcon importSprite(String path) {
		URL sprite = getClass().getResource(path);
		if (sprite == null) {
			return null;
		} else
			return new ImageIcon(sprite);
	}

	/**
	 * importSprites
	 * 
	 * imports all of the sprite for the playerCharacter
	 */
	private void importSprites() {
		ImageIcon lemon0 = importSprite("/textures/Lemon/Right0.png");
		lemonSpriteMap.put(Sprite.LEMONR0, lemon0);
		ImageIcon lemon1 = importSprite("/textures/Lemon/Right1.png");
		lemonSpriteMap.put(Sprite.LEMONR1, lemon1);
		ImageIcon lemon2 = importSprite("/textures/Lemon/Right2.png");
		lemonSpriteMap.put(Sprite.LEMONR2, lemon2);
		ImageIcon lemon3 = importSprite("/textures/Lemon/Right3.png");
		lemonSpriteMap.put(Sprite.LEMONR3, lemon3);
		ImageIcon lemon4 = importSprite("/textures/Lemon/Right4.png");
		lemonSpriteMap.put(Sprite.LEMONR4, lemon4);
		ImageIcon lemon5 = importSprite("/textures/Lemon/Right5.png");
		lemonSpriteMap.put(Sprite.LEMONR5, lemon5);
		ImageIcon lemon6 = importSprite("/textures/Lemon/Right6.png");
		lemonSpriteMap.put(Sprite.LEMONR6, lemon6);
		ImageIcon lemon7 = importSprite("/textures/Lemon/Right7.png");
		lemonSpriteMap.put(Sprite.LEMONR7, lemon7);
		pauseScreen.setIcon(importSprite("/textures/pauseScreen.png"));
		loadingScreen.setIcon(importSprite("/textures/loadingLevel.png"));
		gameOverScreen.setIcon(importSprite("/textures/gameOver.png"));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see model.IModelObserver#modelChanged()
	 */
	@Override
	public void modelChanged() {
		int currentHealthNumber = model.getHealth();
		currentHealth = Integer.toString(currentHealthNumber);
		health.setText("Health: " + currentHealth);

		int height = model.getPlayerHeight();
		lemonPosition.y = height;
		lemon.setIcon(updateLemonSprite());
		lemon.setLocation(lemonPosition);

		Status status = model.getStatus();
		switch (status) {
		case GAMEOVER: {
			gameOverScreen.setVisible(true);
			break;
		}
		case DEAD: {
			int currentLevelNumber = model.getCurrentLevel();
			currentLevel = Integer.toString(currentLevelNumber);
			level.setText(currentLevel);
			int currentLivesNumber = model.getCurrentLives();
			currentLives = Integer.toString(currentLivesNumber);
			lives.setText(currentLives);
			loadingScreen.setVisible(true);
			level.setVisible(true);
			lives.setVisible(true);
			break;
		}
		case ALIVE: {
			gameOverScreen.setVisible(false);
			loadingScreen.setVisible(false);
			level.setVisible(false);
			lives.setVisible(false);
			break;
		}
		}

		if (model.getLoadingLevel()) {

			int currentLevelNumber = model.getCurrentLevel();
			currentLevel = Integer.toString(currentLevelNumber);
			level.setText(currentLevel);
			int currentLivesNumber = model.getCurrentLives();
			currentLives = Integer.toString(currentLivesNumber);
			lives.setText(currentLives);

			level.setVisible(true);
			lives.setVisible(true);
			loadingScreen.setVisible(true);
		}

		if (model.getPauseState()) {
			health.setVisible(true);
			pauseScreen.setVisible(true);
		} else {
			health.setVisible(true);
			pauseScreen.setVisible(false);
		}
		repaint();
	}

	/**
	 * updateLemonSprite
	 * 
	 * loads a sprite for the playerCharacter based upon the current sprite set
	 * in the playerCharacter
	 * 
	 * @return
	 */
	public Icon updateLemonSprite() {
		int currentLemon = model.getCurrentLemonSprite();
		switch (currentLemon) {
		case 0:
			return lemonSpriteMap.get(Sprite.LEMONR0);
		case 1:
			return lemonSpriteMap.get(Sprite.LEMONR1);
		case 2:
			return lemonSpriteMap.get(Sprite.LEMONR2);
		case 3:
			return lemonSpriteMap.get(Sprite.LEMONR3);
		case 4:
			return lemonSpriteMap.get(Sprite.LEMONR4);
		case 5:
			return lemonSpriteMap.get(Sprite.LEMONR5);
		case 6:
			return lemonSpriteMap.get(Sprite.LEMONR6);
		case 7:
			return lemonSpriteMap.get(Sprite.LEMONR7);
		default:
			return lemonSpriteMap.get(Sprite.LEMONR0);
		}
	}

}
